home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / edit / yame.zip / YAME.DOC < prev    next >
Text File  |  1994-12-18  |  43KB  |  1,222 lines

  1.  
  2.  ───────────────────────────────────────────────────────────────
  3.    ▄ ▄     ▄ ▄         ▄         ▄ ▄       ▄ ▄   ▄ ▄ ▄ ▄ ▄ ▄ ▄ 
  4.    ▄ ▄     ▄ ▄       ▄ ▄ ▄       ▄ ▄ ▄   ▄ ▄ ▄     ▄ ▄     ▄ ▄ 
  5.    ▄ ▄     ▄ ▄     ▄ ▄   ▄ ▄     ▄ ▄ ▄ ▄ ▄ ▄ ▄     ▄ ▄       ▄ 
  6.    ▄ ▄     ▄ ▄   ▄ ▄       ▄ ▄   ▄ ▄ ▄ ▄ ▄ ▄ ▄     ▄ ▄   ▄     
  7.      ▄ ▄ ▄ ▄     ▄ ▄       ▄ ▄   ▄ ▄   ▄   ▄ ▄     ▄ ▄ ▄ ▄     
  8.        ▄ ▄       ▄ ▄ ▄ ▄ ▄ ▄ ▄   ▄ ▄       ▄ ▄     ▄ ▄   ▄     
  9.        ▄ ▄       ▄ ▄       ▄ ▄   ▄ ▄       ▄ ▄     ▄ ▄         
  10.        ▄ ▄       ▄ ▄       ▄ ▄   ▄ ▄       ▄ ▄     ▄ ▄       ▄ 
  11.        ▄ ▄       ▄ ▄       ▄ ▄   ▄ ▄       ▄ ▄     ▄ ▄     ▄ ▄ 
  12.      ▄ ▄ ▄ ▄     ▄ ▄       ▄ ▄   ▄ ▄       ▄ ▄   ▄ ▄ ▄ ▄ ▄ ▄ ▄  
  13.  
  14.  ───────────────────────────────────────────────────────────────
  15.                      Yet Another Memo Editor
  16.                          (for dBASE IV)
  17.  
  18.                      version 1.00  12/18/94
  19.  
  20.  
  21.  
  22.  
  23.  
  24.       Copyright (c) 1994 Kenneth Chan. All rights reserved.
  25.  
  26. ═════════════════════════════════════════════════════════════════
  27.                            QUICK START
  28. ═════════════════════════════════════════════════════════════════
  29.  
  30. Y.COM is the name of the YAME executable file.
  31.  
  32. Y.COM can also be LOADed and CALLed as a dBASE module. More on
  33. that later.
  34.  
  35. Depending on how much control you want over YAME, using it may be
  36. as simple as:
  37.  
  38. (1) Add/modify the WP entry of the CONFIG.DB file
  39.  
  40.     Add
  41.  
  42.         WP = Y
  43.  
  44.     if Y.COM is on your PATH. If it is not on your PATH, specify
  45.     the full pathname to Y.COM.
  46.  
  47. That's it! To see YAME in action:
  48.  
  49.     (a) Start dBASE
  50.     (b) Go to the dot prompt
  51.     (c) SET STATUS ON, if it is not ON already
  52.     (d) USE a database with a memo field (or CREATE one)
  53.     (e) EDIT a record (or APPEND one)
  54.     (f) Cursor to a memo field
  55.     (g) Press Ctrl-Home to zoom into the memo field
  56.     (h) You are now in YAME. Cursor around; try entering and
  57.         deleting some text. Notice the line and column indicator
  58.     (i) To save and quit, press Ctrl-End or Ctrl-W. To quit
  59.         without saving, press Esc (if you made any changes, you
  60.         will be asked if you want to lose them).
  61.  
  62. If you want more control over YAME, you can use the YAMEPARM.BIN
  63. module:
  64.  
  65. (2) LOAD the YAMEPARM module into memory.
  66.  
  67.     From the dot prompt
  68.  
  69.         LOAD YAMEPARM
  70.  
  71. (3) CALL YAMEPARM with the parameters you want to have in effect
  72.     the next time you edit a memo field.
  73.  
  74.     For example, if you want to edit the memo in a 51-character
  75.     wide window in the middle of the screen, with a 50-character
  76.     word wrap margin:
  77.  
  78.         CALL YAMEPARM with "/@5,15,16,65 /m50"
  79.  
  80. EDIT and zoom into the memo field again and see the new
  81. parameters take effect.
  82.  
  83. You may CALL YAMEPARM with as often as you want, and use a
  84. different set of parameters each time.
  85.  
  86. (4) When done, you should uninstall YAMEPARM by CALLing it with
  87.     no parameters:
  88.  
  89.         CALL YAMEPARM
  90.  
  91. Here endeth the Quick Start.
  92.  
  93.  
  94. ═════════════════════════════════════════════════════════════════
  95.                            ABOUT YAME
  96. ═════════════════════════════════════════════════════════════════
  97.  
  98. What it is
  99. ----------
  100.  
  101.     YAME is a paragraph-oriented word-wrap text editor. That
  102.     means that YAME is designed for narrative text passages, like
  103.     long comments or case histories.
  104.  
  105.  
  106. What it is not
  107. --------------
  108.  
  109.     YAME is not a line-oriented text editor. It is not suited for
  110.     writing programs. It is not a word processor; it has no
  111.     formatting or printing capabilities.
  112.  
  113.  
  114. What's good about it
  115. --------------------
  116.  
  117.     YAME is faster than the built-in memo editor, especially with
  118.     large files. The built-in editor suffers greatly with large
  119.     files in two areas: cursor movement and I/O. Compare the time
  120.     required to read in a 60 KB memo and what happens when you
  121.     try to hold down the PgDn key all the way to the bottom.
  122.  
  123.     YAME can operate in any size window, even one that is one
  124.     character high and one character wide.
  125.  
  126.     YAME supports different word-wrap margins! The margin can be
  127.     any value from 1 to 65,534 characters.
  128.  
  129.     YAME can limit the size of your memo fields to a total number
  130.     of bytes, a total number of lines, or both.
  131.  
  132.     YAME allows an alternate save and exit key, in addition to
  133.     Ctrl-W and Ctrl-End.
  134.  
  135.     YAME can be run as a .COM file or LOADed and CALLed as a .BIN
  136.     file, which avoids swapping overhead.
  137.  
  138.     YAME can be reconfigured between calls without leaving dBASE.
  139.  
  140.     YAME has a read-only mode.
  141.  
  142.     YAME detects and works with the dBASE status line.
  143.  
  144.     YAME supports the classic WordStar diamond cursor keys.
  145.  
  146.  
  147. What's not so good
  148. ------------------
  149.  
  150.     YAME can only edit files up to 64K in size.
  151.  
  152.  
  153. What's dependent on your point of view
  154. --------------------------------------
  155.  
  156.     YAME does not have mouse support.
  157.  
  158.     YAME has no menus.
  159.  
  160.  
  161. What's best about YAME
  162. ----------------------
  163.  
  164.     YAME is written by a dBASE developer for dBASE developers,
  165.     and is responsive to your input.
  166.  
  167.  
  168. Why?
  169. ----
  170.  
  171.     "I forget exactly how I ended up 'volunteering' to write a
  172.     memo editor replacement back on BORBBS. But I thought it was
  173.     doable and an interesting challenge. So I dove in and look at
  174.     all the trouble I've caused!" -- Kenneth Chan
  175.  
  176.  
  177. How do you pronounce it?
  178. ------------------------
  179.  
  180.     The preferred pronunciation is (YAH-meh); it should not rhyme
  181.     with "name" or "same".
  182.  
  183.  
  184. By the way
  185. ----------
  186.  
  187.     YAME is perfectly suited for general purpose word-wrap text
  188.     editing. It doesn't have to be run under dBASE.
  189.  
  190.  
  191. ═════════════════════════════════════════════════════════════════
  192.                           USER'S GUIDE
  193. ═════════════════════════════════════════════════════════════════
  194.  
  195. Through the use of ComBin(tm) technology, there are two ways to
  196. invoke YAME: (1) as a standard DOS .COM executable; and (2) as a
  197. dBASE-CALLable .BIN. The same file (Y.COM) can be run either way.
  198. Each method has its advantages.
  199.  
  200.  
  201. As a .COM file
  202. --------------
  203.  
  204. By adding the WP = Y entry in your CONFIG.DB file, dBASE will use
  205. YAME as its external memo editor and run the Y.COM program
  206. whenever you edit a memo.
  207.  
  208. Y.COM is just like any DOS executable program. It takes
  209. parameters:
  210.  
  211.     Y [<switches>] <filespec>
  212.  
  213. dBASE will copy the memo field into a temporary file, tack the
  214. name of that temporary file at the end of whatever comes after
  215. the WP =, and pass the whole thing to DOS. This means that you
  216. can include any default parameters that you use with YAME on the
  217. WP line.  For example, if you prefer the line and column
  218. indicators off by default, the WP line would look like:
  219.  
  220.     WP = Y /I
  221.  
  222. You may also run Y.COM with the RUN/! command or RUN() function.
  223. The .COM invocation is simpler, although at present, dBASE has
  224. some quirks with external memo editors (see Quirks below).
  225.  
  226.  
  227. As a .BIN file
  228. --------------
  229.  
  230. Y.COM can also be LOADed and CALLed like a .BIN file. The
  231. advantage of this is that there is no overhead associated with
  232. shelling out to run a program. One hitch is that a .BIN cannot
  233. allocate memory, so another .BIN will be used as editing buffer
  234. space. That module is called YAMEBUFF.BIN. You need to
  235.  
  236.     load YAMEBUFF
  237.  
  238. and then
  239.  
  240.     call YAMEBUFF with <buffer size>
  241.  
  242. Where buffer size can be any number from 1 to 65024 (63.5 K).
  243. This installs the YAMEBUFF buffer. You must then LOAD the Y.COM
  244. file with the command
  245.  
  246.     load Y.COM
  247.  
  248. Note that you must include the .COM extension, since the LOAD
  249. command usually expects a .BIN. You may then CALL the Y module as
  250. needed with the command
  251.  
  252.     call Y with "[<switches>] <filespec>"
  253.  
  254. or the function
  255.  
  256.     call( "Y", "[<switches>] <filespec>" )
  257.  
  258. One other hitch is that you'll need to copy the memo field to a
  259. temp file before calling YAME, and then copy the file back to the
  260. memo field when done. This is done with the COPY MEMO TO and
  261. APPEND MEMO FROM OVERWRITE commands, respectively:
  262.  
  263.     copy memo MEMO_FLD to MEMO_TMP.$DB
  264.     call Y with "MEMO_TMP.$DB"
  265.     append memo MEMO_FLD from MEMO_TMP.$DB overwrite
  266.  
  267. Before quitting dBASE, you should uninstall the YAMEBUFF buffer
  268. with the command (note no parameters)
  269.  
  270.     call YAMEBUFF
  271.  
  272.  
  273. Parameter passing
  274. -----------------
  275.  
  276. Essential to the flexibility of YAME is its capability to
  277. dynamically configure itself without leaving dBASE. This is
  278. achieved with tiered parameters. When invoked, YAME attempts to
  279. process four stages of parameters:
  280.  
  281.     (1) Default
  282.     (2) .COM invocation
  283.     (3) YAMEPARM
  284.     (4) .BIN invocation
  285.  
  286. When run as a .COM, YAME will go through stages 1, 2, and 3; for
  287. .BIN invocation, stages 1, 3, and 4. Some examples will make
  288. things clearer:
  289.  
  290. Let's say that you want to run YAME as your external memo editor,
  291. a .COM invocation. You want a margin of 50 for most of your memo
  292. fields. The default word wrap margin is 65 characters. You add
  293. the following WP line to your CONFIG.DB file:
  294.  
  295.     WP = Y /m50
  296.  
  297. Every time you edit a memo, dBASE runs YAME. When YAME starts, it
  298. sets its margin to the default, 65. It then sees the parameter
  299. specified when it was run, a margin of 50. That is the margin
  300. that is used.
  301.  
  302. If you then want a margin of 70 for a particular memo, you'll
  303. need to override the default margin of 65 and the margin of 50
  304. specified on the WP line of the CONFIG.DB file. This is when
  305. YAMEPARM comes in. You CALL YAMEPARM with parameters that you
  306. want:
  307.  
  308.     call YAMEPARM with "/m70"
  309.  
  310. The next time YAME runs, it will set its default margin, then the
  311. margin of 50, and then see the parameter in YAMEPARM and use
  312. that. If you had another memo with a margin of 40, you'd:
  313.  
  314.     call YAMEPARM with "/m40"
  315.  
  316. and when you want to revert back to the WP parameters, you'd:
  317.  
  318.     call YAMEPARM
  319.  
  320. Parameters set up through YAMEPARM will stay in effect until
  321. different parameters are sent, or until you uninstall YAMEPARM by
  322. CALLing it with no parameters.
  323.  
  324.  
  325. For a .BIN invocation, you'd use YAMEPARM to set your personal
  326. defaults:
  327.  
  328.     call YAMEPARM with "/m50"
  329.  
  330. From then on, every time you CALL Y, YAME will first set the
  331. margin to its default, 65, then see the margin in YAMEPARM and
  332. use that. If you then wanted a margin of 70, you'd include the
  333. margin parameter in the CALL:
  334.  
  335.     call Y with "/m70 MEMO_TMP.$DB"
  336.  
  337. If you ever want to go back to your personal default of 50, leave
  338. out the margin parameter in the CALL to YAME:
  339.  
  340.     call Y with "MEMO_TMP.$DB"
  341.  
  342. And if you ever want to use YAME's default of 65, you can
  343.  
  344.     call YAMEPARM
  345.  
  346. to clear your personal default as well.
  347.  
  348.  
  349. Sample .COM implementation
  350. --------------------------
  351.  
  352. For this example, you'll be using YAME as a direct memo editor
  353. replacement. Your .DBF has two memo fields: ARG_PRO and ARG_CON.
  354. You want to show them side-by-side on the screen, with a border
  355. around each. This yields a word wrap margin of 37:
  356.  
  357.     ( 80 cols / 2 memos ) - 2 for border - 1 = 37
  358.  
  359. You'll want the margin to be one less than the width of the
  360. window so that the cursor can rest at the end of the longest line
  361. without the memo panning back and forth. In this example, you put
  362. the YAME executable, Y.COM, in your \DBASE directory, but \DBASE
  363. is not on your PATH, so you add the following line to your
  364. CONFIG.DB file:
  365.  
  366.     WP = \DBASE\Y /m37 /ss
  367.  
  368. By using the /SS switch, YAME will save the memos in dBASE-native
  369. format, with soft carriage returns. Without them, dBASE will not
  370. display the memos with the word-wrapping you got while within
  371. YAME.
  372.  
  373. You'll need YAMEPARM to dynamically configure YAME during your
  374. dBASE session, so one of first things you do is:
  375.  
  376.     load YAMEPARM
  377.  
  378. from the dot prompt. You then proceed to design the screen form
  379. normally. You want the memo fields to display as open windows.
  380. Draw the windows normally and note the coordinates of the
  381. corners. Since you want them to display equally side-by-side,
  382. you're guaranteed that the columns will be 0, 39, 40 and 79.
  383. Let's say that the rows you end up with after laying everything
  384. out are 11 on the top and 19 on the bottom.
  385.  
  386. For the ARG_PRO field on the left, you add the following to the
  387. Permit edit if option:
  388.  
  389.     call( "YAMEPARM", "/@11,0,19,39 /bd" ) = "T"
  390.  
  391. When CALLing YAMEPARM with the CALL() function, CALL() will
  392. return the parameter string. YAMEPARM confirms that the parameter
  393. is received by changing the first character in the parameter
  394. string to a "T". If YAMEPARM fails, the first character will be
  395. changed to an "F" (see More about YAMEPARM and YAMEBUFF below).
  396. SET EXACT must be OFF (the default) for this "begins with T"
  397. comparison to return .T., thus allowing the GET while setting the
  398. parameters for that field. The ARG_CON field would be similarly
  399. configured:
  400.  
  401.     call( "YAMEPARM", "/@11,40,19,79 /bd" ) = "T"
  402.  
  403. In both of these cases, you're using a double border line for the
  404. window when you're actually editing the memo. You can now
  405. generate the .FMT and use the form. 
  406.  
  407. When all done, you should uninstall and unload YAMEPARM:
  408.  
  409.     call YAMEPARM
  410.     release module YAMEPARM
  411.  
  412. It is absolutely critical that you uninstall YAMEPARM by CALLing
  413. it with no parameters before RELEASing it and/or QUITting dBASE.
  414.  
  415.  
  416. Sample .BIN implementation
  417. --------------------------
  418.  
  419. To implement the same two fields with a .BIN invocation of YAME,
  420. the first thing you will need is to load and install the edit
  421. buffer:
  422.  
  423.     load YAMEBUFF
  424.     call YAMEBUFF with 8000
  425.  
  426. You don't want the pro and con arguments to be too wordy, so
  427. you've set the limit of the memo field to approximately 8 KB.
  428. This is the largest memo that YAME will allow. This limit is
  429. enforced by the YAME program, and does not actually affect the
  430. amount of memory occupied by YAMEBUFF.BIN
  431.  
  432. You will also need two generic routines, one to display the memo,
  433. and one to handle the keyboard:
  434.  
  435. PROCEDURE DispMemo
  436.   parameter cMemoFld, nTop, nLft, nBtm, nRht
  437.   private nOldWidth, n1
  438.   nOldWidth = set( "MEMOWIDTH" )
  439.   *-- Set MEMOWIDTH for window
  440.   set memowidth to nRht - nLft - 2
  441.   *-- Draw border
  442.   @ nTop, nLft to nBtm, nRht
  443.   @ nTop + 1, nLft + 1 clear to nBtm - 1, nRht - 1
  444.   n1 = 1
  445.   *-- Display each line
  446.   do while n1 < nBtm - nTop
  447.     @ nTop + n1, nLft + 1 say mline( &cMemoFld., n1 )
  448.     n1 = n1 + 1
  449.   enddo
  450.   set memowidth to nOldWidth
  451. RETURN
  452.  
  453. FUNCTION MemoKey
  454.   parameters nTop, nLft, nBtm, nRht, cExtraParm
  455.   *-- Make sure extra parameter is defined
  456.   if pcount() < 5
  457.     cExtraParm = ""
  458.   endif
  459.   private nRow, nCol, lLoop, cYAMEPARM, cMemoFld, cColorFld
  460.   *-- Construct YAME parameter string
  461.   cYAMEParm = "/m" + ltrim( str( nRht - nLft - 2 )) + " /@" + ;
  462.     ltrim( str( nTop )) + "," + ltrim( str( nLft )) + "," + ;
  463.     ltrim( str( nBtm )) + "," + ltrim( str( nRht )) + ;
  464.     " /bd " + cExtraParm + " MEMO_TMP.$DB"
  465.   cMemoFld = varread()
  466.   nRow = row()
  467.   nCol = col()
  468.   *-- Get the COLOR OF FIELDS
  469.   cColorFld = substr( set( "ATTRIBUTES" ), ;
  470.     rat( ",", set( "ATTRIBUTES" )) + 1 )
  471.   if file( "MEMO_TMP.$DB" )
  472.     erase MEMO_TMP.$DB
  473.   endif
  474.   copy memo &cMemoFld. to MEMO_TMP.$DB
  475.   lLoop = .t.
  476.   do while lLoop
  477.     nKey = inkey( 0 )
  478.     do case
  479.       case nKey = 29 .or. nKey = -8 && Ctrl-Home or F9
  480.         save screen to sMemoKey
  481.         *-- Invoke YAME; exit code returned in parameter string
  482.         call Y with cYAMEParm
  483.         restore screen from sMemoKey
  484.         release screen sMemoKey
  485.         *-- Check exit code to see if file was saved
  486.         if cYAMEParm = "0"
  487.           *-- Update memo field
  488.           append memo &cMemoFld. from MEMO_TMP.$DB overwrite
  489.         endif
  490.         *-- If memo marker is outside the window
  491.         if nRow < nTop .or. nRow > nBtm .or. ;
  492.           nCol + 3 < nLft .or. nCol > nRht
  493.           *-- Update the memo marker
  494.           @ nRow, nCol say iif( len( &cMemoFld. ) = 0, "memo", ;
  495.             "MEMO" ) color &cColorFld.
  496.         else
  497.           *-- Redisplay memo
  498.           do DispMemo with cMemoFld, nTop, nLft, nBtm, nRht
  499.         endif
  500.         *-- Overwrite exit code with original slash
  501.         cYAMEParm = stuff( cYAMEParm, 1, 1, "/" )
  502.         *-- Do not KEYBOARD Ctrl-Home
  503.         nKey = 0
  504.       case "," + ltrim( str( nKey )) + "," $ ;
  505.         ",1,3,4,5,6,9,13,17,18,19,23,24,27,-400,"
  506.         *-- These keys will move the cursor, let them pass
  507.       case nKey > 0 .and. nKey < 256
  508.         *-- Ignore all other non-function keys
  509.         nKey = 0
  510.       otherwise
  511.         *-- KEYBOARD function key to allow for ON KEY traps
  512.         keyboard "{" + ltrim( str( nKey )) + "}"
  513.         *-- but don't leave
  514.         nKey = 0
  515.     endcase
  516.     if nKey # 0
  517.       *-- Type key
  518.       keyboard "{" + ltrim( str( nKey )) + "}" clear
  519.       *-- Quit loop
  520.       lLoop = .f.
  521.     endif
  522.     *-- Move cursor back after possible memo redraw
  523.     @ nRow, nCol say ""
  524.   enddo
  525.   if file( "MEMO_TMP.$DB" )
  526.     erase MEMO_TMP.$DB
  527.   endif
  528. *-- Return .T. to read stuffed keystroke
  529. RETURN .t.
  530.  
  531.  
  532. The DispMemo procedure simply uses the dBASE function MLINE() to
  533. display the memo in a simulated window. The MemoKey() function is
  534. to be used in the WHEN clause of a memo GET. During a READ, when
  535. the cursor arrives at the memo field, it waits for a keystroke;
  536. every time Ctrl-Home or F9 is pressed, YAME is invoked. Keys that
  537. would move the cursor to another field are passed through, and
  538. all other keys are ignored.
  539.  
  540. To actually GET the two memo fields, your code would look
  541. something like this:
  542.  
  543. clear
  544. @ 12, 1 get ARG_PRO ;
  545.   when MemoKey( 11, 0, 19, 39, "" )
  546. do DispMemo with "ARG_PRO", 14, 0, 21, 39
  547. @ 12,41 get ARG_CON ;
  548.   when MemoKey( 11, 40, 19, 79, "" )
  549. do DispMemo with "ARG_CON", 14, 40, 21, 79
  550. read
  551.  
  552. You'll want to place the memo marker at the top left corner of
  553. the inside of the window, so that when the cursor gets to the
  554. memo field, it will appear to be at the beginning of the memo.
  555. After placing the marker, you use the DispMemo procedure to
  556. display the memo window over it. From then on, the markers will
  557. be obscured.
  558.  
  559. When you're all done, don't forget to uninstall and unload the
  560. edit buffer:
  561.  
  562.     call YAMEBUFF
  563.     release module YAMEBUFF
  564.  
  565. It is absolutely critical that you uninstall YAMEBUFF by CALLing
  566. it with no parameters before RELEASing it and/or QUITting dBASE.
  567.  
  568.  
  569. More about YAMEPARM and YAMEBUFF
  570. --------------------------------
  571.  
  572. YAMEPARM and YAMEBUFF communicate with Y.COM by using one of the
  573. User Interrupt Vectors (Int 60h - 66h) or some normally unused
  574. ROM BASIC vectors (97h-AFh). Some of these vectors are used by
  575. other programs and drivers, but there are usually a few
  576. available.
  577.  
  578. YAMEPARM and YAMEBUFF each use their own vector, so if both of
  579. them are LOADed and installed, they use two vectors. If they are
  580. not uninstalled before they are RELEASEd and/or you QUIT dBASE,
  581. those vectors will not be cleared. Pretty soon, there will be no
  582. free vectors, and YAMEPARM and YAMEBUFF will fail.
  583.  
  584. Therefore, it is absolutely critical that you uninstall YAMEPARM
  585. and YAMEBUFF by CALLing them with no parameters before RELEASing
  586. them and/or QUITting dBASE. Again, IT IS ABSOLUTELY CRITICAL THAT
  587. YOU UNINSTALL YAMEPARM AND YAMEBUFF BY CALLING THEM WITH NO
  588. PARAMETERS BEFORE RELEASING THEM AND/OR QUITTING DBASE.
  589.  
  590. YAMEPARM will indicate successful installation by changing the
  591. first letter of the parameter string to a "T"; failure is
  592. indicated by an "F".  For example, the sequence
  593.  
  594.     cParm = "/@11,0,19,39 /bd"
  595.     call YAMEPARM with cParm
  596.  
  597. will change the memory variable cParm to
  598.  
  599.     "T@11,0,19,39 /bd"
  600.  
  601. if YAMEPARM is installed successfully and
  602.  
  603.     "F@11,0,19,39 /bd"
  604.  
  605. if it is not. Once installed successfully, further CALLs to
  606. YAMEPARM should return "T", until of course YAMEPARM is RELEASEd
  607. or dBASE QUITs. Since the memory variable is changed, the
  608. original character, usually a "/", must be restored before using
  609. the parameter string again.
  610.  
  611. Note that every time you pass parameters to YAMEPARM, they stay
  612. memory resident. You do not have to CALL YAMEPARM before every
  613. single memo. You only need to use YAMEPARM when the parameters
  614. change.
  615.  
  616. YAMEBUFF operates in a similar manner. You CALL YAMEBUFF with the
  617. maximum file size you want to allow. This limit is enforced by
  618. the YAME program, and does not affect the amount of memory
  619. occupied by YAMEBUFF.BIN. YAMEBUFF.BIN is almost 64 KB in size;
  620. most of it, 63.5 KB or 65024 bytes, is buffer space; the
  621. remainder is the YAMEBUFF installation code. Even if you
  622.  
  623.     call YAMEBUFF with 4000
  624.  
  625. to keep the memo fields below 4 KB, YAMEBUFF will still occupy 64
  626. KB of memory. In these situations, you can use the smaller buffer
  627. file, YAMEBUF8.BIN, which has 8 KB (8192 bytes) of buffer space.
  628. YAMEBUF8 works exactly like YAMEBUFF, except that the maximum
  629. maximum is only 8 KB, not 63.5 KB. Do not have YAMEBUFF and
  630. YAMEBUF8 LOADed simulataneously.
  631.  
  632. YAMEBUFF (and YAMEBUF8) will return the amount of space that was
  633. registered as the maximum allowable file size. In most cases,
  634. this means that your parameter will be returned unchanged. The
  635. exceptions are:
  636.     (1) You asked for more space than there was in the .BIN, i.e.
  637.         more than 65024 for YAMEBUFF and 8192 for YAMEBUF8. In
  638.         those cases, those limits will be registered and
  639.         returned.
  640.     (2) You asked for more than 65535 bytes. Don't do that.
  641.     (3) YAMEBUFF was unable to install itself. In this case,
  642.         YAMEBUFF will return 0. You should verify that the return
  643.         value is greater than zero to make sure that YAMEBUFF was
  644.         installed before your try to edit something.
  645.  
  646. If either YAMEPARM or YAMEBUFF return failure codes ("F" and 0,
  647. respectively), this means that there were no available vectors to
  648. hook into. This is because either you've already got a ton of
  649. gizmos loaded in your system, or, more likely, you forgot to
  650. uninstall YAMEPARM or YAMEBUFF before RELEASing them and/or
  651. QUITting dBASE. Remember that it is absolutely critical that you
  652. uninstall YAMEPARM and YAMEBUFF by CALLing them with no
  653. parameters before RELEASing them and/or QUITting dBASE.
  654.  
  655.  
  656. Using YAME with dBASE 5 for DOS
  657. -------------------------------
  658.  
  659. dBASE 5 for DOS includes a fully windowed word-wrap EDITOR object
  660. that finally supports variable margins. (In fact, as you resize
  661. the editor window, it re-wraps on-the-fly -- pretty slick.)
  662.  
  663. If you still want to use YAME, it does work in dBASE 5 (as does
  664. virtually all dBASE IV code) with no modifications. YAME is
  665. modal, which means that when YAME is running, you cannot switch
  666. to another on-screen form or menu, especially with the mouse,
  667. since the mouse is disabled while YAME is active.
  668.  
  669. dBASE 5 has a new SET WP command, which allows you to change the
  670. memo editor as needed during your dBASE session. Therefore, you
  671. do not need to set the WP = option in the CONFIG.DB file. You
  672. can:
  673.  
  674.     set wp to Y.COM
  675.  
  676. when you want to use YAME as your memo editor, and
  677.  
  678.     set wp to
  679.  
  680. to switch back to the built-in memo editor. Note that when using
  681. dBASE IV-style @ GETs, the built-in memo editor is the old dBASE
  682. IV memo editor, and when using CUA forms with an ENTRYFIELD
  683. DataLink'd to a memo field, the built-in memo editor is the new
  684. EDITOR object.
  685.  
  686. You cannot use YAME as your SET WP memo editor with CUA forms,
  687. since the exit codes returned by Y.COM cause dBASE 5 to think
  688. there was an error ("Invalid path or filename") if you exit the
  689. memo with saving. You can still use YAME with CUA forms by
  690. setting up an event handler that runs or calls YAME manually.
  691.  
  692. Finally, the EDITOR object in dBASE 5 for DOS uses a soft
  693. carriage return and a normal carriage return together to indicate
  694. the end of a word-wrapped line. The built-in memo editor in dBASE
  695. IV uses a soft carriage return and a line feed. This means that
  696. memos edited by the EDITOR object in dBASE 5 will not be read
  697. properly by the built-in memo editor in dBASE IV. On the other
  698. hand, the EDITOR object understands dBASE IV memos when it first
  699. reads them, and saves them in its own format. YAME can read
  700. either type of soft carriage return, but when saving with soft
  701. carriage returns with the /SS switch, saves in dBASE IV format.
  702.  
  703.  
  704. ═════════════════════════════════════════════════════════════════
  705.                             REFERENCE
  706. ═════════════════════════════════════════════════════════════════
  707.  
  708. Keys
  709. ----
  710.  
  711.     Keys are listed in function groups.
  712.  
  713.     Stopping what you started
  714.     -------------------------
  715.         Esc                   Quit without saving
  716.         Ctrl-End    Ctrl-W    Save and quit
  717.                     Ctrl-K/D  Save and quit
  718.                     Ctrk-K/X  Save and quit
  719.  
  720.     Moving around
  721.     -------------
  722.         Home        Ctrl-Z    Beginning of line
  723.         End         Ctrl-B    End of line
  724.         Up          Ctrl-E    Up a line
  725.         Down        Ctrl-X    Down a line
  726.         Left        Ctrl-S    Left one character
  727.         Right       Ctrl-D    Right one character
  728.         PgUp        Ctrl-R    Up one window
  729.         PgDn        Ctrl-C    Down one window
  730.         Ctrl-Left   Ctrl-A    Left one word
  731.         Ctrl-Right  Ctrl-F    Right one word
  732.         Ctrl-PgUp             Beginning of file
  733.         Ctrl-PgDn             End of file
  734.                     Alt-R     Beginning of paragraph
  735.                     Alt-C     End of paragraph
  736.  
  737.     Inserting and deleting
  738.     ----------------------
  739.         Insert      Ctrl-V    Toggle insert mode
  740.         Del         Ctrl-G    Delete one character to right
  741.         Backspace   Ctrl-H    Delete one character to left
  742.                     Ctrl-T    Delete word
  743.                     Ctrl-Y    Delete line
  744.                     Ctrl-N    Insert new line
  745.         Tab         Ctrl-I    Tab forward
  746.         Shift-Tab             Tab backward
  747.  
  748.     Block
  749.     -----
  750.                     Ctrl-K/B  Drop block anchor
  751.                     Ctrl-K/K  Raise block anchor
  752.                     Ctrl-K/H  Unmark block
  753.                     Ctrl-K/C  Copy block
  754.                     Ctrl-K/V  Move block
  755.                     Ctrl-K/Y  Delete block
  756.  
  757.     Word wrapping
  758.     -------------
  759.                     Alt-B     Rewrap paragraph
  760.  
  761.     Control characters (ASCII values 1-31) except the tab, line
  762.     feed, and carriage return (ASCII 9, 10, and 13) can be
  763.     entered using the ALT-keypad method.
  764.  
  765.  
  766. Switches/Parameters
  767. -------------------
  768.  
  769. All switches start with a slash and are separated by spaces.
  770. There must be no spaces within each parameter. The parameters
  771. that may be used with either Y.COM or YAMEPARM.BIN are:
  772.  
  773.     /@[<top>][,[<left>][,[<bottom>][,[<right>]]]]
  774.  
  775.         /@ specifies the window size. You may leave out any of
  776.         the dimensions. The coordinates are zero-based.
  777.  
  778.     /B[S|D|P|<border definition string>]
  779.  
  780.         /BS single line border
  781.         /BD double line border
  782.         /BP panel border
  783.         /B  no border
  784.  
  785.         The <border definition string> follows the format of SET
  786.         BORDER, as follows:
  787.  
  788.             [<1>][,[<2>][,[<3>][,[<4>][,[<5>][,[<6>][,[<7>][,[<8>
  789.             ]]]]]]]]
  790.  
  791.         where each number 1 through 8 MUST be a decimal value for
  792.         any ASCII character. The required order for specifying
  793.         the sides and corners using 1 through 8 is:
  794.  
  795.            5╔═══════════════1═══════════════╗6
  796.             ║                               ║
  797.             ║                               ║
  798.             3                               4
  799.             ║                               ║
  800.             ║                               ║
  801.            7╚═══════════════2═══════════════╝8
  802.  
  803.     /C[<text>][,[<block>][,[<border>][,[<indicator>]]]]
  804.  
  805.         /C specifies the colors, using dBASE-standard color
  806.         descriptors.
  807.  
  808.         <text> the color of text
  809.         <block> the color of blocked text
  810.         <border> the color of the border
  811.         <indicator> the color of the line and column indicators
  812.  
  813.     /I[+|-|<row>,<col>]
  814.  
  815.         /I- disables the line and column indicators
  816.  
  817.         /I+ enables the line and column indicators
  818.  
  819.         /I<row>,<col> enables the line and column indicators at
  820.         the specified coordinates. The indicator is 17 columns
  821.         wide.
  822.  
  823.     /M[<margin>]
  824.  
  825.         /M specifies the word wrap margin. You may use any number
  826.         from 1 to 65534.
  827.  
  828.         /M0 specifies no word wrap.
  829.  
  830.     /R[+|-]
  831.  
  832.         /R+ displays the file in read-only mode. No editing is
  833.         possible.
  834.  
  835.         /R- disables read-only mode (if had been enabled)
  836.  
  837.     /S[Y|S|H]
  838.  
  839.         /SY Save in YAME format (default)
  840.         /SS Save with soft CRs
  841.         /SH Save with hard CRs
  842.  
  843.         By default, YAME saves paragraphs as single long lines of
  844.         text. This is the fastest save mode, and facilitates
  845.         importing by other programs that do word wrap, since
  846.         there are no extra characters.
  847.  
  848.         dBASE's built-in memo editor uses soft carriage returns
  849.         (hex 8D0A) to mark line breaks, and uses them to
  850.         determine how to display the memo in a window. By using
  851.         /SS, the margins you use in YAME will be reflected in
  852.         memo windows.
  853.  
  854.         You can also save the file with hard carriage returns
  855.         (hex 0D0A) at the end of the lines. This makes the lines
  856.         in a paragraph separate, as if you had pressed Enter at
  857.         the end of each line. This is useful if you need to print
  858.         the file, or import it into something that does not do
  859.         word wrap.
  860.  
  861.     /T[<tabsize>]
  862.  
  863.         /T specifies the tab size, from 1 to 255 characters
  864.  
  865.     /X[<scancode>]
  866.  
  867.         /X allows you to specify an alternate save & exit key,
  868.         such as F2. You must specify the decimal scancode for the
  869.         appropriate key:
  870.  
  871.         Key         Code    Key         Code    Key         Code
  872.         ----------- ----    ----------- ----    ----------- ----
  873.         F1           59     Shift-F1     84     Ctrl-F1      94
  874.         F2           60     Shift-F2     85     Ctrl-F2      95
  875.         F3           61     Shift-F3     86     Ctrl-F3      96
  876.         F4           62     Shift-F4     87     Ctrl-F4      97
  877.         F5           63     Shift-F5     88     Ctrl-F5      98
  878.         F6           64     Shift-F6     89     Ctrl-F6      99
  879.         F7           65     Shift-F7     90     Ctrl-F7     100
  880.         F8           66     Shift-F8     91     Ctrl-F8     101
  881.         F9           67     Shift-F9     92     Ctrl-F9     102
  882.         F10          68     Shift-F10    93     Ctrl-F10    103
  883.  
  884.         Key         Code    Key         Code    Key         Code
  885.         ----------- ----    ----------- ----    ----------- ----
  886.         Alt-F1      104     Alt-A        30     Alt-N        49
  887.         Alt-F2      105     Alt-B        48     Alt-O        24
  888.         Alt-F3      106     Alt-C        46     Alt-P        25
  889.         Alt-F4      107     Alt-D        32     Alt-Q        16
  890.         Alt-F5      108     Alt-E        18     Alt-R        19
  891.         Alt-F6      109     Alt-F        33     Alt-S        31
  892.         Alt-F7      110     Alt-G        34     Alt-T        20
  893.         Alt-F8      111     Alt-H        35     Alt-U        22
  894.         Alt-F9      112     Alt-I        23     Alt-V        47
  895.         Alt-F10     113     Alt-J        36     Alt-W        17
  896.                             Alt-K        37     Alt-X        45
  897.                             Alt-L        38     Alt-Y        21
  898.                             Alt-M        50     Alt-Z        44
  899.  
  900.     /Z[<byte limit>|L[<line limit>]]
  901.  
  902.         /Z allows you to limit the size of the memo field
  903.         entered, either the total number of bytes with /Z<bytes>
  904.         or the total number of lines with /ZL<lines>. If YAMEBUFF
  905.         is used, the buffer size specified when installing has
  906.         priority. Both a total byte and total line count can be
  907.         specified by using two separate /Z switches.
  908.  
  909.         Using /Z or /ZL with no number will reset the respective
  910.         sizes to their maximum: 65,535 for both.
  911.  
  912.  
  913. Defaults
  914. --------
  915.  
  916. The default settings for YAME are:
  917.  
  918.     Window size:
  919.         Top: row 1
  920.         Left: column 0
  921.         Right: right edge of the screen
  922.         Bottom: if the dBASE status line is detected, the bottom
  923.             row is the row above the status line; if not, the
  924.             bottom of the screen.
  925.         YAME detects and works with most displays at various
  926.             screen sizes.
  927.  
  928.     Border: None
  929.  
  930.     Color: W+/B,RG+/GB,RG+/GB,B/W
  931.  
  932.     Indicators:
  933.         If the status line is detected, the indicators are in the
  934.         middle of the status line, where the built-in memo
  935.         editor's indicators are. If not, the indicators occupy
  936.         row 0.
  937.  
  938.     Margin: 65
  939.  
  940.     Read-Only: Off
  941.  
  942.     Save mode: YAME-native
  943.  
  944.     Tab size: 8
  945.  
  946.  
  947. Return codes
  948. ------------
  949.  
  950. Upon exit, YAME returns the following codes:
  951.  
  952.     0 = Save and exit
  953.         -------------
  954.         The file was saved upon exit by pressing Ctrl-End. If not
  955.         in read-only mode, the file is always rewritten, even if
  956.         no changes were made. If in read-only mode, the file is
  957.         not actually saved, but this code is returned so that you
  958.         can determine the exit key.
  959.  
  960.     1 = Exit without saving
  961.         -------------------
  962.         The file was abandoned by pressing Esc. If any changes
  963.         were made, they were discarded.
  964.  
  965.     2 = No filespec
  966.         -----------
  967.         There was no file specified anywhere along the line, so
  968.         there was nothing to do. When run as a .COM, this will
  969.         cause YAME to print its banner and information screen.
  970.  
  971.     3 = Error opening file
  972.         ------------------
  973.         What YAME thought was the filename (the last non-switch
  974.         parameter it encountered) was invalid in some way,
  975.         usually an invalid drive/directory, or it contained
  976.         invalid characters.
  977.  
  978.     4 = Memory allocation error
  979.         -----------------------
  980.         In the .COM invocation, there was not enough free memory
  981.         to allocate a 64 KB editing buffer. In the .BIN
  982.         invocation, YAME could not find YAMEBUFF.
  983.  
  984. When run as a .COM, these codes are returned as standard DOS
  985. ERRORLEVELs, which are visible in dBASE by using the RUN()
  986. function with the first parameter set to .T., e.g.
  987.  
  988.     nErrLvl = run( .t., "\DBASE\Y.COM", .t. )
  989.  
  990. Remember that when the first parameter is .T., the PATH does not
  991. work; you must specify the full directory and file name.
  992.  
  993. When run as a .BIN, YAME will change the first character of the
  994. parameter string to the appropriate digit. This means that if you
  995. want the return code, you must pass a parameter with your CALL,
  996. even if it is just a blank space, e.g.
  997.  
  998.     if call( "Y", " " ) = "0"    && was the file saved?
  999.  
  1000. If you're using a memory variable for your CALL parameter, don't
  1001. forget to restore the first character (usually a "/") since it
  1002. was overwritten by the return code.
  1003.  
  1004.  
  1005. ═════════════════════════════════════════════════════════════════
  1006.                              QUIRKS
  1007. ═════════════════════════════════════════════════════════════════
  1008.  
  1009. These quirks are not YAME-specific, but rather issues that come
  1010. up when dealing with memo fields. Any or all of them may be
  1011. resolved in future releases of dBASE:
  1012.  
  1013.  
  1014. Shelling out to external memo editor leaves 0-byte files
  1015. --------------------------------------------------------
  1016.  
  1017. When using an external memo editor, dBASE copies the current memo
  1018. field to a temp file with the name TMPnnnnn.$DB, where nnnnn is a
  1019. random 5-digit number. dBASE also creates a 0-byte file of the
  1020. same name in the dBASE temporary directory (usually specified
  1021. with the DBTMP DOS environment variable).
  1022.  
  1023. dBASE does not delete the 0-byte .$DB file when done editing the
  1024. memo field. Successive edits will create more and more of these
  1025. files in the dBASE temporary directory. This has 3 effects:
  1026.     (1) If the temporary directory is the root directory of a
  1027.         drive, you may run out of available directory entries.
  1028.         Don't make the dBASE temporary directory the root
  1029.         directory of a drive.
  1030.     (2) Although they occupy no disk space, all these empty files
  1031.         will reduce performance when the number of directory
  1032.         entries gets very large (in the hundreds).
  1033.     (3) When dBASE quits, those files will still be there,
  1034.         cluttering the directory. Unless the temporary directory
  1035.         is on a RAM disk, you will probably want to delete these
  1036.         files. Don't do a DEL *.$DB while in dBASE, since there
  1037.         are other files with the .$DB extension that are needed
  1038.         by dBASE.
  1039.  
  1040.  
  1041. Returning from external memo editor erases last two lines
  1042. ---------------------------------------------------------
  1043.  
  1044. When dBASE restores the screen after returning from an external
  1045. memo editor, the last two lines on the screen are blank. If you
  1046. are using a format file, the format is refreshed, so the entire
  1047. screen is rewritten, solving the problem.
  1048.  
  1049. If you're not using a format file, as with a READ, those last two
  1050. lines (lines 23 and 24 in 25-line mode) are lost. Since the
  1051. cursor is still on the memo field, it is difficult to refresh the
  1052. screen yourself. It's not impossible, but it is ugly:
  1053.  
  1054. clear
  1055. *-- State variable
  1056. public n_MemoScrn
  1057. *     0 == no checking
  1058. *     1 == initial entry into memo field
  1059. *     2 == grab next key
  1060. *     3 == screen saved
  1061. *-- Set state for initial entry into memo field
  1062. n_MemoScrn = 1
  1063. @  4, 6 get C1                          && Dummy char field
  1064. @  6, 6 get MEMO_FIELD ;
  1065.   when ForcValid() ;
  1066.   valid required MemoScrn() ;
  1067.   error "" ;
  1068.   message " Memo kludge "
  1069. @  8, 6 get C2                          && Dummy char field
  1070. @ 22, 0 to 23,79 double
  1071. read
  1072. release n_MemoScrn
  1073. RETURN
  1074.  
  1075. FUNCTION ForcValid
  1076.   if n_MemoScrn = 1
  1077.     *-- Move to next stage
  1078.     n_MemoScrn = 2
  1079.     *-- Trigger VALID check
  1080.     keyboard "{CTRL-M}"
  1081.     *-- Silence bell
  1082.     set bell to 19,1
  1083.   endif
  1084.   if n_MemoScrn = 0
  1085.     *-- Set state var for next memo field
  1086.     n_MemoScrn = 1
  1087.     *-- Restore bell to default tone
  1088.     set bell to 512,2
  1089.   endif
  1090. RETURN .t.
  1091.  
  1092. FUNCTION MemoScrn
  1093.   private lRet, nKey
  1094.   if n_MemoScrn > 1
  1095.     if n_MemoScrn = 3
  1096.       *-- Restore lines 23 and 24
  1097.       restore screen from sMemoScrn
  1098.       release screen sMemoScrn
  1099.     endif
  1100.     *-- Wait for keypress
  1101.     nKey = inkey( 0 )
  1102.     *-- Return VALID false to force next action to occur in
  1103.     *-- current field
  1104.     lRet = .f.
  1105.     *-- Clear VALID error message
  1106.     keyboard " "
  1107.     *-- Ctrl-Home; edit memo
  1108.     if nKey = 29
  1109.       save screen to sMemoScrn
  1110.       n_MemoScrn = 3
  1111.       *-- Open memo and force recheck
  1112.       keyboard "{CTRL-HOME}{CTRL-M}"
  1113.     else
  1114.       *-- Don't stop the next key
  1115.       n_MemoScrn = 0
  1116.       *-- Type the key that was trapped
  1117.       keyboard "{" + ltrim( str( nKey )) + "}"
  1118.     endif
  1119.   else
  1120.     *-- Pass key through
  1121.     lRet = .t.
  1122.     *-- Must init PRIVATE memvar
  1123.     nKey = 0
  1124.   endif
  1125. RETURN lRet
  1126.  
  1127. Suggestions for other workarounds are welcome.
  1128.  
  1129.  
  1130. Aborting READ after adding new memo block corrupts memo
  1131. -------------------------------------------------------
  1132.  
  1133. If while READing a memo field
  1134.     (1) enough text is added to a memo field such that another
  1135.         memo block in the .DBT is required
  1136.     (2) that memo is saved (with Ctrl-End in the editor), and
  1137.     (3) changes to the record are discarded (with Esc back in
  1138.         dBASE)
  1139. the memo may become corrupted. This is because since the memo
  1140. grew, it is saved in a new chain of memo blocks, and the old
  1141. blocks are marked as free; but since the changes to the record
  1142. are discarded, the pointers in the .DBF are not updated, so they
  1143. point to the now free space, confusing everything.
  1144.  
  1145. This may be the cause of previously mysterious memo corruption,
  1146. since a specific sequence of events and conditions are required.
  1147. This problem does not manifest itself with EDIT.
  1148.  
  1149. This problem has been traced to a conflict with the mouse. The
  1150. current workaround is to disable the mouse in the WHEN clause of
  1151. the GET, and to re-enable it in the VALID REQUIRED clause. Or you
  1152. can disable the mouse entirely. Since YAME does not support the
  1153. mouse, this isn't that bad. The GET for a memo field would look
  1154. like this:
  1155.  
  1156. @  6, 6 get MEMO_FIELD ;
  1157.   when MouseOff() ;
  1158.   valid required MouseOn()
  1159. ...
  1160.  
  1161. FUNCTION MouseOff
  1162.   set mouse off
  1163. RETURN .t.
  1164.  
  1165. FUNCTION MouseOn
  1166.   set mouse on
  1167. RETURN .t.
  1168.  
  1169.  
  1170. Memo window wraps at column 65 or soft return, whichever is first
  1171. -----------------------------------------------------------------
  1172.  
  1173. dBASE will always display a memo in a window wrapped at column
  1174. 65, or at a soft return code, whichever comes first. By using the
  1175. /SS option of YAME, soft return codes are inserted into the text
  1176. so that dBASE will display the memo properly. However, if the
  1177. margin is wider than 65, this won't work; dBASE will wrap at
  1178. column 65 first, and then again at the inserted soft return later
  1179. in the line.
  1180.  
  1181. If you plan to use memo windows, don't make the margins wider
  1182. than 65 characters. An alternative is to use the DispMemo
  1183. procedure, which works for all widths.
  1184.  
  1185.  
  1186. ═════════════════════════════════════════════════════════════════
  1187.                              SUPPORT
  1188. ═════════════════════════════════════════════════════════════════
  1189.  
  1190. Support is provided in the dBASE forum on CompuServe. You can GO
  1191. DBASE and post your questions in the dBASE IV Programming or
  1192. Addons section. Please do not ask technical questions through
  1193. personal mail.
  1194.  
  1195. Lately, I've also been hanging out on the MetroLink Database
  1196. conference.
  1197.  
  1198. If you have any questions, suggestions, anomaly reports, etc.,
  1199. contact:
  1200.     Kenneth Chan            CompuServe: 72662,1305
  1201.     PO Box 50245              Internet: 72662.1305@compuserve.com
  1202.     Pasadena CA 91115-0245
  1203.  
  1204. YAME is available as YAME.ZIP in two primary locations: the DBASE
  1205. forum on CompuServe, and at ftp.borland.com.
  1206.  
  1207. YAME is made available to the dBASE community free of charge, in
  1208. the spirit that made BORBBS great. However, YAME is not in the
  1209. public domain; all rights are reserved by the author.
  1210.  
  1211. On the other hand, YAME is provided as-is, with no warranty of
  1212. any kind. The user (that's you) takes full responsibility. The
  1213. author cannot and does not warrant, guarantee, or make any
  1214. representations regarding the appropriateness, use of, or results
  1215. of the use of YAME; the author will not be liable for any
  1216. damages, including but not limited to data loss, system damage,
  1217. hair loss, back pain, tension headache, blurred vision, and/or
  1218. the inability to simultaneously pat your head and rub your tummy.
  1219.  
  1220.  
  1221. *-- EoF: YAME.DOC
  1222.